﻿package com.winglish.as3.ui{
	import flash.display.*;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	//import com.greensock.TweenLite;
	
	public class WScrollBar extends Sprite{
		//To set thumb mininum size
		static private var _thumbMinSize: int = 15;
		
		static public function GET( $sc: MovieClip, $obj: Object = null, $isChangeThumbSize: Boolean = true ): WScrollBar{
			var obj: Object = {};
			if( !$sc ) return null;
			obj.sc = $sc;
			obj.upbtn = ( $sc.controlbar.hasOwnProperty( "upbtn" ) ) ? $sc.controlbar.upbtn : null;
			obj.downbtn = ( $sc.controlbar.hasOwnProperty( "downbtn" ) ) ? $sc.controlbar.downbtn : null;
			
			if( obj.upbtn !== null ){
				obj.hasButton = true;
			}
			else{
				obj.hasButton = false;
			}
			//trace( "hasButton :", obj.hasButton );
			
			obj.track = $sc.controlbar.track;
			obj.thumb = $sc.controlbar.thumb;
			obj.controlbar = $sc.controlbar;			
			obj.content = $sc.content;
			obj.masker = $sc.masker;
			//Validation is Object Data
			if( $obj !== null ){
				if( $obj.width ) obj.sw = $obj.width;
				if( $obj.height ) obj.sh = $obj.height;
				if( $obj.offset ){
					obj.moveNum = $obj.offset;
				}
				else{
					obj.moveNum = 5;
				}
				
			}
			obj.isChangeThumbSize = $isChangeThumbSize;
			
			var scrollbar: WScrollBar = new WScrollBar( Checker.GET );
			scrollbar.init( obj );
			return scrollbar;
		}
		
		private var _sc: MovieClip;
		private var _track: MovieClip;
		private var _thumb: MovieClip;
		private var _upbtn: MovieClip;
		private var _downbtn: MovieClip;
		private var _controlbar: MovieClip;
		private var _content: MovieClip;
		private var _masker: MovieClip;
		private var _contentAry: Array;
		
		private var _hasButton: Boolean;
		
		private var _scrollSpeed: Number;
		private var _yOffset: Number;
		private var _yMin: Number;
		private var _yMax: Number;
		private var _sw: Number;
		private var _sh: Number;
		private var _moveNum: int;
				
		private var _isRemove: Boolean;
		private var _isChangeThumbSize: Boolean;
		
		public function WScrollBar( $checker: Checker ){}
		//initial function
		private function init( $obj: Object ): void{	
			_sc = $obj.sc;
			_hasButton = $obj.hasButton;
			if( _hasButton ){
				_upbtn = $obj.upbtn;
				_downbtn = $obj.downbtn;
			}
			
			_track = $obj.track;
			_thumb = $obj.thumb;
			_controlbar = $obj.controlbar;			
			_content = $obj.content;
			_masker = $obj.masker;
			//Validation is Object Data
			if( $obj !== null ){
				if( $obj.sw ){
					_sw = $obj.sw;
					setScWidth( _sw );
				}
				if( $obj.sh ){
					_sh = $obj.sh;
					setScHeight( _sh );
				}
				if( $obj.moveNum ){
					_moveNum = $obj.moveNum;
				}
			}
			_isChangeThumbSize = $obj.isChangeThumbSize;
			
			_contentAry = new Array();
			
			setScrollBarArea();
			addEvent();
			setContentArray();
		}
		//----------------------------  public method start  --------------------------//
		//Add Content
		public function addObject( $do: DisplayObject, $x: Number = 0, $y: Number = NaN ): void{
			if( !$y ){
				if( _content.numChildren == 0 ){
					$do.y = 0;
				}
				else{
					$do.y = _content.height;
				}
			}
			else{
				$do.y = $y;
			}
			$do.x = $x;
			_content.addChild( $do );
			//일괄적으로 content안의 object를 제어할일이 있을라나 -_-? 일단 배열에 담아둠.....
			_contentAry.push( $do );
			setScrollBarArea();
		}
		//Remove Content
		public function removeObject(  $do: DisplayObject = null ): void{
			var len: uint = _contentAry.length;
			for( var i: uint = 0; i < len; i++ ){
				if( $do == _contentAry[ i ] ){
					_content.removeChild( _contentAry[ i ] );
					//content안의 object delete 배열에서도 delete
					_contentAry.splice(i, 1);
				}
			}
			_isRemove = true;
			setScrollBarArea();
		}
		public function update(): void{
			_isRemove = true;
			setScrollBarArea();
		}
		//Coordinates you want to move to
		public function setPosition( $pos: Number ): void{
			if( !_controlbar.visible ) return;
			if( $pos == _thumb.y ) return;
			
			var cMin: Number = 0;
			var cMax: Number = _content.height - _masker.height;
			if(  $pos < cMin ){
				 $pos = cMin;
			}
			if( $pos > cMax ){
				$pos = cMax;
			}
			var cp: Number = ( $pos - cMin ) / ( cMax - cMin );
			var sy: Number = ( cp * ( _yMax - _yMin ) ) + _yMin;
			_thumb.y = sy;
			move();
		}
		//Changing the scroll width area
		public function setWidth( $num: Number ): void{
			if( $num < 1 ){
				trace( "Then the width value does not change" );
			}
			else{
				_sw = $num;
				setScWidth( _sw );
				setScrollBarArea();
			}			
		}
		//Changing the scroll height area
		public function setHeight( $num: Number ): void{
			var hMin: Number = _thumbMinSize + _upbtn.height + _downbtn.height + 10;
			if( $num < hMin ){
				trace( "Then the height value does not change" );
			}
			else{
				_sh = $num;
				setScHeight( _sh );
				setScrollBarArea();
			}			
		}
		//----------------------------  public method end  --------------------------//
		
		//Add to that an array of content already
		private function setContentArray(): void{
			var len: int = _content.numChildren;
			for( var i: int = 0; i < len; i++ ){
				_contentAry.push( _content.getChildAt( i ) );
			}
		}
		//Due to changes in the content area, and scroll the minimum, maximum change
		private function setScrollBarArea(): void{
			if( _isRemove ) drawContentArea();
			var thumbSize: Number = getThumbSize();
			setThumbSize( thumbSize );
			if( _hasButton ){
				_yMin = _upbtn.height;
				_yMax = _track.height - _thumb.height + _yMin;
			}
			else{
				_yMin = 0;
				_yMax = _track.height - _thumb.height;
			}
			
			setChangeThumbPosition();
			if( !_controlbar.visible ) _content.y = 0;//TweenLite.to( content, .5, { y: 0 } );
			if( !_isRemove ) drawContentArea();
			_isRemove = false;
		}
		
		private function setChangeThumbPosition(): void{
			var thumbSize: Number = getThumbSize();
			var thumbHeight: Number = _track.height * thumbSize;
			var thumbMax: Number = thumbHeight + _thumb.y ;
			var trackMax: Number = _track.y + _track.height;
			if( thumbMax > trackMax ) {
				var thumbOffset: Number = thumbMax - trackMax;
				if( _controlbar.visible ) _thumb.y = _thumb.y + thumbOffset;				
			}	
			move();
		}
		//Content area drawing
		private function drawContentArea(): void{
			var g:Graphics = _content.graphics;
			g.clear();
			g.beginFill( 0xFFFFFF, 0 );
			g.drawRect( 0, 0, _content.width, _content.height );
			g.endFill();
		}
		//Change area
		private function setScWidth( $size: Number ): void{
			_masker.width = $size;
			//_controlbar.x = $size;
		}
		//Change area
		private function setScHeight( $size: Number ): void{
			_masker.height = $size;
			if( _hasButton ){
				_track.height = $size - ( _upbtn.height + _downbtn.height );
				_downbtn.y = $size;				
			}
			else{
				//thumb의 이미지가 top, middle, bottom으로 구분되어 질때..
				if( _track.numChildren > 1 ){
					//trace( "track안의 무비클립 갯수는 :", track.numChildren );
					_track.track_mid.height = $size - _track.track_top.height - _track.track_bot.height;
					_track.track_bot.y = $size - _track.track_bot.height;
				}
				else{
					_track.height = $size;
				}				
			}			
		}
		//content area and the mask area is proportional to the value returned
		private function getThumbSize(): Number{
			var thumbSize: Number = _masker.height / _content.height;
			return thumbSize;
		}
		//To set the thumb size
		private function setThumbSize( $size: Number ): void{
			if( $size < 1 ){
				//thumb의 이미지가 top, middle, bottom으로 구분되어 질때..
				if( _thumb.numChildren > 1 ){
					//trace( "thumb안의 무비클립 갯수는 :", thumb.numChildren );
					var thumbHeight: Number = _track.height * $size;
					var thumbFixHeight: Number = _thumb.thumb_t.height + _thumb.thumb_b.height ;
					//_thumb.thumb_m.height = ( thumbHeight < _thumbMinSize ) ? _thumbMinSize - thumbFixHeight : thumbHeight - thumbFixHeight;
					_thumb.thumb_b.y = _thumb.thumb_m.y + _thumb.thumb_m.height;
				}
				else{//thumb only one case
					if( _isChangeThumbSize ){//thumb size changeable
						_thumb.height = _track.height * $size;
						if( _thumb.height < _thumbMinSize ) _thumb.height = _thumbMinSize;
					}
					else{
						//
					}					
				}				
				if( !_controlbar.visible ) _controlbar.visible = true;					
			}
			else{//Content size is smaller than the size of the scrollBar
				_controlbar.visible = false;
				//thumb.y = yMin;
			}
		}
		//add Event
		private function addEvent(): void{
			_thumb.addEventListener( MouseEvent.MOUSE_DOWN, onDownHandler );			
			_sc.addEventListener( MouseEvent.MOUSE_WHEEL, onWheelHandler );
			if( _hasButton ) _upbtn.addEventListener( MouseEvent.CLICK, onClickHandler );
			if( _hasButton ) _downbtn.addEventListener( MouseEvent.CLICK, onClickHandler );
		}
		//MouseWheel Event Handler
		private function onWheelHandler( $e: MouseEvent ): void{
			if(_controlbar.visible){
				_thumb.y -= $e.delta*_moveNum;			
				move();
			}
		}
		//MouseClick Event Handler
		private function onClickHandler( $e: MouseEvent ): void{
			var str: String = $e.target.name;
			_yOffset = 0;
			switch( str ){
				case "upbtn" :
					_thumb.y -= _moveNum;
					move();
					break;
				case "downbtn" :
					_thumb.y += _moveNum;
					move();
					break;
			}
		}
		//MouseDown Event Handler
		private function onDownHandler( $e: MouseEvent ): void{
			_yOffset = mouseY - _thumb.y;
			addEventListener( Event.ENTER_FRAME, onEnterFrameHandler );
			_sc.stage.addEventListener( MouseEvent.MOUSE_UP, onUpHandler );			
		}
		//MouseUp Event Handler
		private function onUpHandler( $e: MouseEvent ): void{
			removeEventListener( Event.ENTER_FRAME, onEnterFrameHandler );
			_sc.stage.removeEventListener( MouseEvent.MOUSE_UP, onUpHandler );
		}
		//MouseMove Event Handler
		private function onEnterFrameHandler( $e: Event ): void{
			_thumb.y = mouseY - _yOffset;
			move();
		}
		//scroll 움직임에 따른 content 좌표값을 도출 및 TweenLite를 이용 하여 이동
		//isClick 변수는 scroll과 상관없음 오직 up, down Button에 클릭이 됬는지 안됬는지만 판단.
		private function move(): void{
			if( _thumb.y <= _yMin ){
				_thumb.y = _yMin;
			}
			else if( _thumb.y >= _yMax ){
				_thumb.y = _yMax;
			}
			var sp: Number = ( _thumb.y - _yMin ) / ( _yMax - _yMin );
			var cy: Number = sp * ( _content.height - _masker.height );
			//TweenLite.to( content, .5, { y: -cy } );
			_content.y = -cy;
		}
	}
}